#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
业务数据模拟生成脚本
用于生成测试数据填充到数据库中
"""

import os
import sys
import random
from datetime import datetime, date, timedelta
from faker import Faker

# 添加项目路径到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from app import app, db, Book, Publisher, SalesData, Inventory, Review, Logistics, BookCategory, BookTag
from app import DailySalesSummary, BookSalesRanking, CategorySalesSummary, InventoryTurnover
from app import PublisherSalesRanking, CategoryInventorySummary, RegionalSalesSummary, DocumentStatistics

# 初始化Faker
fake = Faker('zh_CN')

def clear_existing_data():
    """清空现有数据"""
    print("清空现有数据...")
    DocumentStatistics.query.delete()
    RegionalSalesSummary.query.delete()
    CategoryInventorySummary.query.delete()
    PublisherSalesRanking.query.delete()
    InventoryTurnover.query.delete()
    CategorySalesSummary.query.delete()
    BookSalesRanking.query.delete()
    DailySalesSummary.query.delete()
    Review.query.delete()
    Logistics.query.delete()
    BookTag.query.delete()
    BookCategory.query.delete()
    Inventory.query.delete()
    SalesData.query.delete()
    Book.query.delete()
    Publisher.query.delete()
    db.session.commit()
    print("数据清空完成")

def generate_publishers(count=20):
    """生成出版社数据"""
    print(f"生成 {count} 条出版社数据...")
    publishers = []
    publisher_names = set()  # 用于跟踪已生成的出版社名称
    
    while len(publishers) < count:
        # 生成唯一的出版社名称
        name = fake.company() + "出版社"
        if name not in publisher_names:
            publisher_names.add(name)
            publisher = Publisher(
                name=name,
                address=fake.address(),
                contact=fake.phone_number()
            )
            db.session.add(publisher)
            publishers.append(publisher)
    
    db.session.commit()
    print(f"出版社数据生成完成，共 {len(publishers)} 条")
    return publishers

def generate_books(publishers, count=100):
    """生成图书数据"""
    print(f"生成 {count} 条图书数据...")
    books = []
    categories = ["文学", "科技", "教育", "儿童", "政治", "经济", "生活", "艺术", "历史", "哲学"]
    
    for i in range(count):
        # 随机选择出版社
        publisher = random.choice(publishers)
        
        book = Book(
            title=fake.sentence(nb_words=6),
            isbn=fake.isbn13(),
            authors=fake.name(),
            publisher=publisher.name,
            publish_date=fake.date_between(start_date='-10y', end_date='today').strftime('%Y年%m月'),
            price=f"￥{random.randint(20, 150)}.00",
            hot_index=round(random.uniform(6.0, 9.9), 2),
            cover_image=f"/static/img/{random.randint(1000001, 1000100)}.jpg",
            description=fake.paragraph(nb_sentences=5)
        )
        db.session.add(book)
        books.append(book)
    
    db.session.commit()
    
    # 为每本书添加分类和标签
    for book in books:
        # 添加分类
        category_count = random.randint(1, 3)
        selected_categories = random.sample(categories, min(category_count, len(categories)))
        for category in selected_categories:
            book_category = BookCategory(
                book_id=book.id,
                category=category
            )
            db.session.add(book_category)
            
        # 添加标签
        tags = fake.words(nb=3, unique=True)
        for tag in tags:
            book_tag = BookTag(
                book_id=book.id,
                tag=tag
            )
            db.session.add(book_tag)
    
    db.session.commit()
    print(f"图书数据生成完成，共 {len(books)} 条")
    return books

def generate_inventory(books):
    """生成库存数据"""
    print("生成库存数据...")
    inventories = []
    for book in books:
        inventory = Inventory(
            book_id=book.id,
            quantity=random.randint(0, 1000),
            location=fake.city() + "仓库"
        )
        db.session.add(inventory)
        inventories.append(inventory)
    db.session.commit()
    print(f"库存数据生成完成，共 {len(inventories)} 条")
    return inventories

def generate_sales_data(books, publishers):
    """生成销售数据"""
    print("生成销售数据...")
    sales_data_list = []
    for book in books:
        # 每本书生成1-5条销售记录
        for _ in range(random.randint(1, 5)):
            publisher = random.choice(publishers) if random.random() > 0.3 else None
            sales_data = SalesData(
                book_id=book.id,
                publisher_id=publisher.id if publisher else None,
                quantity=random.randint(1, 100),
                batch_count=random.randint(1, 20),
                sales_date=fake.date_between(start_date='-2y', end_date='today'),
                amount=round(random.uniform(10.0, 500.0), 2)
            )
            db.session.add(sales_data)
            sales_data_list.append(sales_data)
    db.session.commit()
    print(f"销售数据生成完成，共 {len(sales_data_list)} 条")
    return sales_data_list

def generate_reviews(books):
    """生成评论数据"""
    print("生成评论数据...")
    reviews = []
    for book in books:
        # 每本书生成0-10条评论
        for _ in range(random.randint(0, 10)):
            review = Review(
                book_id=book.id,
                username=fake.user_name(),
                content=fake.paragraph(nb_sentences=3),
                likes=random.randint(0, 1000),
                comments=random.randint(0, 100)
            )
            db.session.add(review)
            reviews.append(review)
    db.session.commit()
    print(f"评论数据生成完成，共 {len(reviews)} 条")
    return reviews

def generate_logistics(books, publishers):
    """生成物流数据"""
    print("生成物流数据...")
    logistics_list = []
    statuses = ["入库", "捡货", "出库", "运输", "签收"]
    
    for book in books:
        # 每本书生成0-3条物流记录
        for _ in range(random.randint(0, 3)):
            publisher = random.choice(publishers) if random.random() > 0.3 else None
            logistics = Logistics(
                book_id=book.id,
                publisher_id=publisher.id if publisher else None,
                status=random.choice(statuses),
                location=fake.city(),
                details=fake.sentence()
            )
            db.session.add(logistics)
            logistics_list.append(logistics)
    db.session.commit()
    print(f"物流数据生成完成，共 {len(logistics_list)} 条")
    return logistics_list

def generate_daily_sales_summary():
    """生成每日销售汇总指标数据"""
    print("生成每日销售汇总指标数据...")
    summaries = []
    today = date.today()
    
    # 生成过去90天的数据
    for i in range(90):
        sales_date = today - timedelta(days=i)
        summary = DailySalesSummary(
            date=sales_date,
            total_quantity=random.randint(100, 1000),
            total_amount=round(random.uniform(2000.0, 20000.0), 2),
            book_count=random.randint(20, 100)
        )
        db.session.add(summary)
        summaries.append(summary)
    db.session.commit()
    print(f"每日销售汇总指标数据生成完成，共 {len(summaries)} 条")
    return summaries

def generate_book_sales_ranking(books):
    """生成图书销售排行指标数据"""
    print("生成图书销售排行指标数据...")
    rankings = []
    periods = ["daily", "weekly", "monthly", "yearly"]
    today = date.today()
    
    for period in periods:
        # 为每个周期生成20本排行图书
        period_books = random.sample(books, min(20, len(books)))
        for i, book in enumerate(period_books):
            ranking = BookSalesRanking(
                book_id=book.id,
                ranking_period=period,
                ranking_value=i+1,
                sales_quantity=random.randint(50, 500),
                sales_amount=round(random.uniform(1000.0, 10000.0), 2),
                statistic_date=today
            )
            db.session.add(ranking)
            rankings.append(ranking)
    db.session.commit()
    print(f"图书销售排行指标数据生成完成，共 {len(rankings)} 条")
    return rankings

def generate_category_sales_summary():
    """生成分类销售汇总指标数据"""
    print("生成分类销售汇总指标数据...")
    summaries = []
    categories = ["文学", "科技", "教育", "儿童", "政治", "经济", "生活", "艺术", "历史", "哲学"]
    today = date.today()
    
    for category in categories:
        summary = CategorySalesSummary(
            category=category,
            sales_quantity=random.randint(100, 1000),
            sales_amount=round(random.uniform(2000.0, 20000.0), 2),
            statistic_date=today
        )
        db.session.add(summary)
        summaries.append(summary)
    db.session.commit()
    print(f"分类销售汇总指标数据生成完成，共 {len(summaries)} 条")
    return summaries

def generate_inventory_turnover(books):
    """生成库存周转率指标数据"""
    print("生成库存周转率指标数据...")
    turnovers = []
    periods = ["monthly", "quarterly"]
    today = date.today()
    
    for book in books[:50]:  # 为前50本书生成数据
        for period in periods:
            turnover = InventoryTurnover(
                book_id=book.id,
                turnover_rate=round(random.uniform(0.5, 3.0), 2),
                sales_quantity=random.randint(20, 200),
                average_inventory=random.randint(50, 500),
                statistic_period=period,
                statistic_date=today
            )
            db.session.add(turnover)
            turnovers.append(turnover)
    db.session.commit()
    print(f"库存周转率指标数据生成完成，共 {len(turnovers)} 条")
    return turnovers

def generate_publisher_sales_ranking(publishers):
    """生成出版社销售排行指标数据"""
    print("生成出版社销售排行指标数据...")
    rankings = []
    periods = ["daily", "weekly", "monthly", "yearly"]
    today = date.today()
    
    for period in periods:
        # 为每个周期生成10家排行出版社
        period_publishers = random.sample(publishers, min(10, len(publishers)))
        for i, publisher in enumerate(period_publishers):
            ranking = PublisherSalesRanking(
                publisher_id=publisher.id,
                ranking_period=period,
                ranking_value=i+1,
                total_sales_quantity=random.randint(100, 1000),
                total_sales_amount=round(random.uniform(2000.0, 20000.0), 2),
                book_count=random.randint(5, 50),
                statistic_date=today
            )
            db.session.add(ranking)
            rankings.append(ranking)
    db.session.commit()
    print(f"出版社销售排行指标数据生成完成，共 {len(rankings)} 条")
    return rankings

def generate_category_inventory_summary():
    """生成分类库存汇总指标数据"""
    print("生成分类库存汇总指标数据...")
    summaries = []
    categories = ["文学", "科技", "教育", "儿童", "政治", "经济", "生活", "艺术", "历史", "哲学"]
    today = date.today()
    
    for category in categories:
        summary = CategoryInventorySummary(
            category=category,
            total_quantity=random.randint(100, 1000),
            total_value=round(random.uniform(2000.0, 20000.0), 2),
            book_count=random.randint(10, 100),
            statistic_date=today
        )
        db.session.add(summary)
        summaries.append(summary)
    db.session.commit()
    print(f"分类库存汇总指标数据生成完成，共 {len(summaries)} 条")
    return summaries

def generate_regional_sales_summary():
    """生成地区销售汇总指标数据"""
    print("生成地区销售汇总指标数据...")
    summaries = []
    regions = ["北京", "上海", "广州", "深圳", "杭州", "南京", "武汉", "成都", "西安", "重庆"]
    today = date.today()
    
    for region in regions:
        summary = RegionalSalesSummary(
            region=region,
            total_sales_quantity=random.randint(100, 1000),
            total_sales_amount=round(random.uniform(2000.0, 20000.0), 2),
            book_count=random.randint(20, 100),
            statistic_date=today
        )
        db.session.add(summary)
        summaries.append(summary)
    db.session.commit()
    print(f"地区销售汇总指标数据生成完成，共 {len(summaries)} 条")
    return summaries

def generate_document_statistics():
    """生成电子单证统计指标数据"""
    print("生成电子单证统计指标数据...")
    statistics = []
    document_types = ["新书书目", "采购单", "发货单", "收货单", "书目变更单", "可用库存"]
    today = date.today()
    
    for i in range(30):  # 生成30天的数据
        statistic_date = today - timedelta(days=i)
        for doc_type in document_types:
            statistic = DocumentStatistics(
                document_type=doc_type,
                count=random.randint(10, 1000),
                statistic_date=statistic_date
            )
            db.session.add(statistic)
            statistics.append(statistic)
    db.session.commit()
    print(f"电子单证统计指标数据生成完成，共 {len(statistics)} 条")
    return statistics

def main():
    """主函数"""
    print("开始生成模拟数据...")
    
    with app.app_context():
        # 清空现有数据
        clear_existing_data()
        
        # 生成业务数据
        publishers = generate_publishers(20)
        books = generate_books(publishers, 100)
        generate_inventory(books)
        generate_sales_data(books, publishers)
        generate_reviews(books)
        generate_logistics(books, publishers)
        
        # 生成指标数据
        generate_daily_sales_summary()
        generate_book_sales_ranking(books)
        generate_category_sales_summary()
        generate_inventory_turnover(books)
        generate_publisher_sales_ranking(publishers)
        generate_category_inventory_summary()
        generate_regional_sales_summary()
        generate_document_statistics()
        
        print("所有模拟数据生成完成！")

if __name__ == '__main__':
    main()